<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>寄生式继承</title>
  </head>
  <body>
    <h3>寄生式继承</h3>
    <h4>
      上一章节：原型式继承，里面对父类的重写都是放在上下文中通过
      .操作符来进行的，不是特别优雅。
    </h4>
    <h4>
      寄生式继承，就是在原型式继承基础上，通过一个函数对齐进行封装，而这类函数也是属于设计模式之一的工厂模式。
    </h4>
    <h4>优化：相对于原型式继承，可以传参。</h4>
    <h4>缺点：对象如果是复合数据类型的数据，会造成数据混乱。</h4>
    <script>
      let parentObj = {
        name: "未初始化的人",
        data: {
          a: 1,
          b: 2,
          c: 3,
        },
        sayData: function () {
          // 这里还不能直接打印对象出来，因为是一个指针，总是指向最新的数据...
          console.log(this.name +  " 的数据如下：");
          console.dir(this.data.a);
          console.dir(this.data.b);
          console.dir(this.data.c);
          console.log("我的数据结束====");
        },
        setDataA: function () {
          this.data.a = 666;
        },
      };

      // 这边仅使用Object.create() 来实现，避免代码量过多。
      function childrenFactory(name, job) {
        // 这里返回的是一个空的对象，obj放在了原型上了，所以只能修改temp中的数据。
        let temp = Object.create(parentObj);
        temp.name = name;
        temp.job = job ? job : "没工作";
        temp.sayJob = function () {
          console.log(`${this.name} 的工作是 ${this.job} ...`);
        };
        return temp;
      }

      let person1 = childrenFactory("钟先生", "程序员");
      let person2 = childrenFactory("刘小姐", "清洁阿姨");

      // 未修改数据
      console.log("===未修改数据的时候...");
      person1.sayData();
      person2.sayData();

      console.log("===修改钟先生一个人的数据的时候...");
      person1.setDataA();
      person1.sayData();
      person2.sayData();

      console.log(person1);
      console.log(person2);
    </script>
  </body>
</html>
